<script setup lang="ts">
import "@antv/x6-plugin-dnd/dist/index.css"
import { computed, defineComponent, h, onMounted, ref, shallowRef } from "vue"
import type { IPackAntvX6 } from "../inter"
import { sum } from "lodash-es";
//
import { Dnd } from "@antv/x6-plugin-dnd";

const { main, list } = defineProps<IPackAntvX6.NodelistProps>();

// const isExpand = ref(true)
// const handleToggleExpand = () => {
//     isExpand.value = !isExpand.value;
// }

const search = ref("")
const handleInput = (e: any) => {
    console.log(e)
    search.value = e?.target?.value || '';
}

const dnd = shallowRef<Dnd>()
const handleDrag = (item: IPackAntvX6.NodelistItem, evt: MouseEvent) => {
    if (!main.graph.isInit) return;
    // const { icon, label } = item;
    const md = { ...item, shape: 'default-node', data: item };
    dnd.value?.start(main.graph.createNode(md), evt)
}

const Item = defineComponent(({ item }) => {
    let cls: any = undefined;
    if (item.children) {
        cls = item.children.map((d: any) => h(Item, { item: d }))
    }
    const show = computed(() => {
        if (item.fixed === true) {
            return true;
        }
        if (!search.value) {
            isExpand.value = false;
            return true;
        }
        const f = (item: any): boolean => {
            let r = false;
            if (item.children) {
                for (const e of item.children) {
                    r = r || f(e)
                }
            }
            const l: number[] = [item.name, item.label, item.desc].map(s => s?.toLowerCase().indexOf(search.value.toLowerCase()) > -1 ? 1 : 0);
            const b = sum(l);
            return r || b > 0;
        }
        const bool = f(item)
        isExpand.value = bool;
        return bool;
    })

    const isExpand = ref(item?.fixed === true)
    const handleToggleExpand = (e: Event) => {
        e.stopPropagation();
        e.preventDefault();
        if (item.fixed === true) {
            return;
        }
        isExpand.value = !isExpand.value;
    }

    return () => cls ? h('div', { class: `${show.value ? "is-show" : "is-hide"} w-full  ${item.fixed ? 'flex-1 overflow-hidden flex flex-col' : ''}`, onClick: handleToggleExpand }, [
        h('div', { class: `_nodelist-item flex items-center gap-6px w-full box-border p-x-10px p-y-4px select-none ${item.fixed === true ? 'is-fixed' : ''}  ${item.class || ''}` }, [
            item.icon ? typeof item.icon == 'string' ? h('b', { class: `${item.icon}` }) : h(item.icon) : '',

            h('b', { class: "flex-1 truncate", title: item.label + ' :: ' + item.desc }, item.label),
            item.fixed === true ? '' : h('span', { class: ` i-uiw:right transition-transform-500 ${isExpand.value ? 'is-open rotate-90' : 'is-close rotate-0'}` })
        ]),
        h('div', { class: `_children-box p-l-4px grid box-border w-full overflow-hidden  ${(isExpand.value) ? 'is-open' : 'is-close'}` }, h('div', { class: `min-h-0 w-full ${item.fixed ? 'overflow-auto scrollbar-thin' : 'overflow-hidden'}` }, cls))
    ]) : h('div', { class: `_nodelist-item flex items-center gap-6px w-full box-border p-x-10px p-y-4px cursor-pointer select-none hover-bg-#ffffff88  ${show.value ? "is-show" : "is-hide"} ${item.class || ''}`, onMousedown: (e) => handleDrag(item, e) }, [
        item.icon ? typeof item.icon == 'string' ? h('b', { class: `text-18px ${item.icon}` }) : h(item.icon) : '',
        h('b', { class: "truncate flex-1", title: item.label + ' :: ' + item.desc }, item.label)])
}, { props: ['item'] })

const nodelistBoxRef = ref<HTMLDivElement>();

//
let flag = false;
if (!main.graph.isInit) {
    flag = true;
    main.graph.onMounted((graph) => {
        dnd.value = new Dnd({
            target: graph,
            dndContainer: nodelistBoxRef.value,
        })
    })
}

onMounted(() => {
    if (flag == false) {
        dnd.value = new Dnd({
            target: main.graph,
            dndContainer: nodelistBoxRef.value,
        })
    }

})

const handleClear = () => {
    search.value = '';
}

</script>

<template>
    <div :class="[':uno: h-full w-full p-4px box-border _nodelist text-3.5']" @click.stop="">
        <!-- 搜索 -->
        <div class=":uno: flex items-center gap-2 h-10 b-b-1px b-solid b-0 m-x-2 ">
            <div class="flex-1 flex items-center gap-2 b-1px b-solid rd-1 p-x-1 ">
                <i class="i-iconoir:search w-1.2em h-1.2em"></i>
                <input :value="search" @input="handleInput" placeholder="" />
                <div v-show="search" @click="handleClear" class="i-fontisto:close op-60 hover-op-100 cursor-pointer"></div>
            </div>
            <!-- <div class="flex items-center text-16 p-4 opacity-80 cursor-pointer hover-opacity-100" @click="handleToggleExpand" :title="isExpand ? '折叠' : '展开'">
                <i v-show="isExpand" class="i-lets-icons:expand-left-stop w-1em h-1em"></i>
                <i v-show="!isExpand" class="i-lets-icons:expand-right-stop w-1em h-1em"></i>
            </div> -->
        </div>
        <!-- 列表 -->
        <div ref="nodelistBoxRef" class="overflow-x-hidden overflow-y-auto mt-8px m-x-2 scrollbar-thin flex flex-col"
            style="height:calc(100% - 40px)">
            <template v-for="item in list" :key="item.label">
                <Item :item="item"></Item>
            </template>

        </div>
    </div>
</template>

<style>
.scrollbar-thin {
    scrollbar-width: thin;
    scrollbar-color:#00000022 transparent;
    scrollbar-gutter: stable;
    &:hover{
        scrollbar-color:#00000088 transparent;
    }
}
._nodelist {
    transition: all 5s ease;

    .is-hide {
        display: none;

        &:has(.is-show) {
            display: block;
        }
    }

    ._children-box {
        transition: all 0.4s ease;
        grid-template-rows: 0fr;

        &.is-open {
            grid-template-rows: 1fr;
        }

        &.is-close {
            grid-template-rows: 0fr;
        }
    }

    ._nodelist-item {
        opacity: .7;
        border-radius: 4px;
        margin-top: 1px;

        &:hover {
            opacity: 1;
        }

        &:has(.is-open) {
            opacity: 1;
        }

        &.is-fixed {
            opacity: 1;
            color: #fff;
            background: #409EFF;
        }
    }
}

.list-enter-active,
.list-leave-active {
    transition: all 0.5s ease;
}

.list-enter-from,
.list-leave-to {
    opacity: 0;
    transform: translateX(30px);
}
</style>